function Interface(name, methods, properties) {
  "use strict";

  methods = methods || [];
  properties = properties || [];
  
  this.name = name;
  this.methods = [];
  this.properties = [];

  for (let i = 0, len = methods.length; i < len; i++) {
    if (typeof methods[i] !== 'string') {
      throw new Error("Konstruktor interfejsu oczekuje na wejściu nazw metod w postaci łańcuchów.");
    }
    this.methods.push(methods[i]);
  }
  
  for (let i = 0, len = properties.length; i < len; i++) {
    if (typeof properties[i] !== 'string') {
      throw new Error("Konstruktor interfejsu oczekuje na wejściu nazw własności w postaci łańcuchów.");
    }
    this.properties.push(properties[i]);
  }
}


Interface.prototype.isImplementedBy = function(obj) {
  "use strict";
  var methodsLen = this.methods.length;
  var propertiesLen = this.properties.length;
  var currentMember;
  
  if (obj) {
    // sprawdzenie metod
    for (let i = 0; i < methodsLen; i++) {
      currentMember = this.methods[i];
      if (!obj[currentMember] || typeof obj[currentMember] !== "function") {
        throw new Error("Obiekt nie implementuje interfejsu " + this.name + ". Nie znaleziono metody " + currentMember + ".");
      } 
    }
    
    //check properties
    for (let i = 0; i < propertiesLen; i++) {
      currentMember = this.properties[i];
      if (!obj[currentMember] || typeof obj[currentMember] === "function") {
        throw new Error("Obiekt nie implementuje interfejsu " + this.name + ". Nie znaleziono własności " + currentMember + ".");
      } 
    }
  } else {
    throw new Error("Brak obiektu do sprawdzenia!");
  }
};

var IHireable = new Interface("IHireable", ["writeCode"], ["name"]);

class SoftwareHouse {
	constructor() {
		this.employees = [];
	}

	hire(dev) {
		IHireable.isImplementedBy(dev);
		this.employees.push(dev);
	}
}